package frog.lazy.framework.http.advice;

import frog.lazy.framework.core.dto.ResultDto;
import frog.lazy.framework.core.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolationException;


@ControllerAdvice
@Slf4j
public class ExceptionAdvice {

    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResultDto handle(Exception e) {
        log.error("【服务器异常】->\n", e);
        return ResultDto.error("服务器异常");
    }

    @ExceptionHandler(value = BizException.class)
    @ResponseBody
    public ResultDto handle(BizException e) {
        log.warn("【业务异常】->{}\n{}", e.getMessage(), e.getCause());
        return ResultDto.builder().code(e.getCode()).msg(e.getMessage()).build();
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultDto handle(MethodArgumentNotValidException e) {
        //按需重新封装需要返回的错误信息
        //解析原错误信息，封装后返回，此处返回非法的字段名称，错误信息
        StringBuffer sb = new StringBuffer("参数错误").append(":");
        for (FieldError error : e.getBindingResult().getFieldErrors()) {
            sb.append("【");
            sb.append(error.getField());
            sb.append("->");
            sb.append(error.getDefaultMessage());
            sb.append("】");
        }
        log.warn("【参数错误】->{}", sb.toString());
        return ResultDto.fail(sb.toString());
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    @ResponseBody
    public ResultDto handle(ConstraintViolationException e) {
        StringBuffer sb = new StringBuffer("参数错误").append(":");
        e.getConstraintViolations().stream().forEach(cons -> {
            sb.append("【");
            sb.append(cons.getMessage());
            sb.append("】;");
        });
        log.warn("【参数错误】->{}", sb.toString());
        return ResultDto.fail(sb.toString());
    }

    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public ResultDto handle(BindException e) {
        StringBuffer sb = new StringBuffer("参数错误").append(":");
        e.getBindingResult().getAllErrors().stream().forEach(be -> {
            sb.append("【");
            sb.append(be.getDefaultMessage());
            sb.append("】;");
        });
        log.warn("【参数错误】->\n{}", sb.toString());
        return ResultDto.fail(sb.toString());
    }

    @ResponseBody
    @ExceptionHandler(value = IllegalArgumentException.class)
    public Object handle(IllegalArgumentException e) {
        log.warn("【校验异常】->{}", e);
        return ResultDto.fail(e.getMessage());
    }
}

